package megadrum.gui;

import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.awt.Point;

public class PopupSlider extends JDialog implements MouseListener, ChangeListener {

    public static final int X_THRESHOLD = 17;
    private JSpinner spinner;
    private JSlider slider;
    private JFormattedTextField textField;
    private boolean mouseExited,  mousePressed; //to help controlling when to show/hide the slider

    //class only valid for spinners with numbermodels with step=1
    public PopupSlider(JSpinner s) {
        super();
        spinner = s;
        textField = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
        slider = new JSlider(
                ((CustomSpinnerModel) s.getModel()).getMinimum(),
                ((CustomSpinnerModel) s.getModel()).getMaximum(),
                ((CustomSpinnerModel) s.getModel()).getIntValue());

        slider.setBorder(new javax.swing.border.EtchedBorder());
        slider.addChangeListener(this);
        slider.addMouseListener(this);
        spinner.addChangeListener(this);
        textField.addMouseListener(this);

        setSize(100, 20);
        setLayout(new BorderLayout());
        add(slider, "Center");
        setModal(false);
        setUndecorated(true);
    }

    public void stateChanged(ChangeEvent e) {
        if (e.getSource() == slider) {
            ((CustomSpinnerModel) spinner.getModel()).setIntValue(slider.getValue());
        } else {
            slider.setValue(((CustomSpinnerModel) spinner.getModel()).getIntValue());
        }
    }

    public void mouseExited(MouseEvent e) {
        mouseExited = true;
        if (!mousePressed &&
                (e.getSource() == slider ||
                !(e.getSource() == textField && e.getY() >= textField.getHeight()))) {
            setVisible(false);
            update(this.getGraphics());
        }
    }

    public void mouseEntered(MouseEvent e) {
        mouseExited = false;
    /*
    if (spinner.isEnabled() && e.getSource() == textField) {
    Point p = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField().getLocationOnScreen();
    Dimension d1 = spinner.getSize();
    p.setLocation(
    (int)(p.getX() - (100 - d1.width)/2),
    (int)(p.getY() + d1.height)
    );
    setLocation(p);
    setVisible(true);
    update(this.getGraphics());
    }
     */
    }

    public void mousePressed(MouseEvent e) {
        mousePressed = true;
    }

    public void mouseReleased(MouseEvent e) {
        mousePressed = false;
        if (mouseExited) {
            setVisible(false);
            update(this.getGraphics());
        }
    }

    public void mouseClicked(MouseEvent e) {
        //when you click once, the slider shows
        if (e.getClickCount() == 1) {
            //if textfield clicked inside the field and not visible yet set it visible
            if (isVisible()) {
                setVisible(false);
            } else {
                Point p = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField().getLocationOnScreen();
                Dimension d1 = spinner.getSize();
                p.setLocation(
                        (int) (p.getX() - (100 - d1.width) / 2),
                        (int) (p.getY() + d1.height));
                setLocation(p);
                setVisible(true);
            }
            update(this.getGraphics());
        }else if(e.getClickCount() == 2){
            setVisible(false);
            String value = JOptionPane.showInputDialog(spinner, "Enter a value:", textField.getText());
            if(value!=null){
                try{
                    spinner.getModel().setValue(new Integer(value));
                }catch(Exception ex){}
            }
        }
    }

    public JSlider getSlider() {
        return slider;
    }

    public void setSlider(JSlider s) {
        slider = s;
    }
}
